package com.naiterui.ehp.bs.payment.exception;

import java.util.Date;

import com.google.common.base.Joiner;
import com.naiterui.ehp.bp.utils.date.DateUtil;

/**
 * <pre>
 * 校验返回结果异常
 * </pre>
 *
 * @author 王泽浩
 * @since 1.0.0
 */
public class CheckException extends RuntimeException {

    /**
     * 订单号
     */
    private final String orderSn;
    /**
     * 支付流水
     */
    private final String tradeSn;

    /**
     * 返回状态码
     */
    private String returnCode;
    /**
     * 返回信息
     */
    private String returnMsg;

    /**
     * 业务结果
     */
    private String resultCode;

    /**
     * 错误代码
     */
    private String errCode;

    /**
     * 错误代码描述
     */
    private String errCodeDes;

    /**
     * 微信支付返回的结果xml字符串
     */
    private String xmlString;

    public CheckException(String message, String orderSn, String tradeSn) {
        super(message);
        this.orderSn = orderSn;
        this.tradeSn = tradeSn;
    }

    public CheckException(String message, String orderSn, String tradeSn, Throwable cause) {
        super(message, cause);
        this.orderSn = orderSn;
        this.tradeSn = tradeSn;
    }

    public CheckException(Builder builder) {
        super(builder.buildErrorMsg());
        this.orderSn = builder.orderSn;
        this.tradeSn = builder.tradeSn;
        this.returnCode = builder.returnCode;
        this.returnMsg = builder.returnMsg;
        this.resultCode = builder.resultCode;
        this.errCode = builder.errCode;
        this.errCodeDes = builder.errCodeDes;
        this.xmlString = builder.xmlString;
    }

    public String getOrderSn() {
        return this.orderSn;
    }

    public String getTradeSn() {
        return this.tradeSn;
    }

    public String getXmlString() {
        return this.xmlString;
    }

    public String getReturnCode() {
        return this.returnCode;
    }

    public String getReturnMsg() {
        return this.returnMsg;
    }

    public String getResultCode() {
        return this.resultCode;
    }

    public String getErrCode() {
        return this.errCode;
    }

    public String getErrCodeDes() {
        return this.errCodeDes;
    }

    public static Builder newBuilder() {
        return new Builder();
    }

    public static final class Builder {
        private String orderSn;
        private String tradeSn;
        private String returnCode;
        private String returnMsg;
        private String resultCode;
        private String errCode;
        private String errCodeDes;
        private String xmlString;

        private Builder() {
        }

        public Builder orderSn(String orderSn) {
            this.orderSn = orderSn;
            return this;
        }

        public Builder tradeSn(String tradeSn) {
            this.tradeSn = tradeSn;
            return this;
        }

        public Builder returnCode(String returnCode) {
            this.returnCode = returnCode;
            return this;
        }

        public Builder returnMsg(String returnMsg) {
            this.returnMsg = returnMsg;
            return this;
        }

        public Builder resultCode(String resultCode) {
            this.resultCode = resultCode;
            return this;
        }

        public Builder errCode(String errCode) {
            this.errCode = errCode;
            return this;
        }

        public Builder errCodeDes(String errCodeDes) {
            this.errCodeDes = errCodeDes;
            return this;
        }

        public Builder xmlString(String xmlString) {
            this.xmlString = xmlString;
            return this;
        }

        public CheckException build() {
            return new CheckException(this);
        }

        String buildErrorMsg() {
            return Joiner.on("\n").skipNulls()
                         .join(new String[]{String.format("【时间】：%s ", DateUtil.formatDate(new Date(), DateUtil.DATE_TIME_FORMAT)),
                                 this.orderSn == null ? null : String.format("【订单号】：%s", this.orderSn),
                                 this.tradeSn == null ? null : String.format("【支付流水号】：%s", this.tradeSn),
                                 this.returnCode == null ? null : String.format("【返回代码】：%s", this.returnCode),
                                 this.returnMsg == null ? null : String.format("【返回信息】：%s", this.returnMsg),
                                 this.resultCode == null ? null : String.format("【结果代码】：%s", this.resultCode),
                                 this.errCode == null ? null : String.format("【错误代码】：%s", this.errCode),
                                 this.errCodeDes == null ? null : String.format("【错误详情】：%s", this.errCodeDes),
                                 this.xmlString == null ? null : "【支付渠道返回的原始报文】：" + this.xmlString});
        }
    }
}
